package com.geo.play;

import info.monitorenter.gui.chart.Chart2D;
import info.monitorenter.gui.chart.ITrace2D;
import info.monitorenter.gui.chart.traces.Trace2DLtd;
import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;

/**
 *
 * @author Geo
 */
public class Lorenz {
    
    private final float sigma = 10;
    private final float  rho = 28;
    private final float  beta = 8/3;
    private final float dt = 0.02f;
    private final float nstop = 100;
    
    
    public static void main(String...args) {
        /*try {
            new Lorenz().solveLorenzRk4Order();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Lorenz.class.getName()).log(Level.SEVERE, null, ex);
        }*/
        
        new Lorenz().solveLorenzRk4Order();
    }
    
    private void solveLorenzRk4Order(){
        
        final Queue<Float> xQ = new LinkedList<>();
        final Queue<Float> yQ = new LinkedList<>();
        
        //Initial Condition
        float x = 1;
        float y = 0;
        float z = 0;
        float t = 0;
        
        while(t<=nstop){
            t = t+dt;
            float X1 = fx(x,y,z);
            float Y1 = fy(x,y,z);
            float Z1 = fz(x,y,z);
            
            float X2 = fx(x+X1*dt/2,y+Y1*dt/2,z+Z1*dt/2);
            float Y2 = fy(x+X1*dt/2,y+Y1*dt/2,z+Z1*dt/2);
            float Z2 = fz(x+X1*dt/2,y+Y1*dt/2,z+Z1*dt/2);
            
            float X3 = fx(x+X2*dt/2,y+Y2*dt/2,z+Z2*dt/2);
            float Y3 = fy(x+X2*dt/2,y+Y2*dt/2,z+Z2*dt/2);
            float Z3 = fz(x+X2*dt/2,y+Y2*dt/2,z+Z2*dt/2);
            
            float X4 = fx(x+X3*dt,y+Y3*dt,z+Z3*dt);
            float Y4 = fy(x+X3*dt,y+Y3*dt,z+Z3*dt);
            float Z4 = fz(x+X3*dt,y+Y3*dt,z+Z3*dt);
            
            x+=(X1+2*X2+2*X3+X4)*dt/6;
            y+=(Y1+2*Y2+2*Y3+Y4)*dt/6;
            z+=(Z1+2*Z2+2*Z3+Z4)*dt/6;
            
            xQ.add(x);
            yQ.add(y);
            
        }
        
        Chart2D chart = new Chart2D();
        // Create an ITrace: 
        // Note that dynamic charts need limited amount of values!!! 
        final ITrace2D trace = new Trace2DLtd(20000); 
        trace.setColor(Color.RED);

        // Add the trace to the chart. This has to be done before adding points (deadlock prevention): 
        chart.addTrace(trace);

        // Make it visible:
        // Create a frame. 
        JFrame frame = new JFrame("MinimalDynamicChart");
        // add the chart to the frame: 
        frame.getContentPane().add(chart);
        frame.setSize(400,300);
        // Enable the termination button [cross on the upper right edge]: 
        frame.addWindowListener(
            new WindowAdapter(){
              public void windowClosing(WindowEvent e){
                  System.exit(0);
              }
            }
         );
        frame.setVisible(true); 
        
        Timer timer = new Timer(true);
        TimerTask task = new TimerTask() {

             @Override
             public void run() {
                if(!xQ.isEmpty() && !yQ.isEmpty()){
                    trace.addPoint(xQ.remove(), yQ.remove());
                }
             }
         };
        
        timer.schedule(task, 1000, 20);
    }
    
    
    
    
    private float fx(float x,float y,float z){
        return sigma*(y-x);
    }
    private float fy(float x,float y, float z){
        return x*(rho-z)-y;
    }
    private float fz(float x,float y,float z){
        return x*y-beta*z;
    }
}